package webv1

import (
	"github.com/gin-gonic/gin"
	"myCloud/contrib"
	"myCloud/dbopr"
	"myCloud/utils"
	"net/http"
)

var (
	commonResponse = map[string]string{"msg": "OK"}
)

func notAuthApiInit(r *gin.RouterGroup) {
	g := r.Group("/user")
	g.POST("/login", contrib.ArgsCheck(userLoginRequest{}), userLoginHandler)
}

func userApiInit(r *gin.RouterGroup) {
	g := r.Group("/user")

	g.POST("/logout", userLogoutHandler)
	g.POST("/logout/all", userLogoutAllHandler)
}

func userLogoutAllHandler(c *gin.Context) {
	token := contrib.GetUserToken(c)
	p := dbopr.NewUserTokenProvider()
	err := p.LogoutToken(token.ID)
	if err != nil {
		abReq(c, http.StatusInternalServerError, "logout session failed.", err)
		return
	}

	c.JSON(http.StatusOK, commonResponse)
}

func userLogoutHandler(c *gin.Context) {
	user := getUser(c)
	p := dbopr.NewUserTokenProvider()
	err := p.LogoutUser(user.ID)
	if err != nil {
		abReq(c, http.StatusInternalServerError, "logout user's all session failed.", err)
		return
	}

	c.JSON(http.StatusOK, commonResponse)
}

type userLoginRequest struct {
	UserName string `json:"user_name"`
	Password string `json:"password"`
	Remember int    `json:"remember"`
}

type userLoginResponse struct {
	UserID       uint   `json:"user_id"`
	UserName     string `json:"user_name"`
	CreatedAt    string `json:"created_at"`
	LastLogin    string `json:"last_login"`
	Avatar       string `json:"avatar"`
	Role         string `json:"role"`
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	ExpireAt     string `json:"expire_at"`
}

func userLoginHandler(c *gin.Context) {
	req := contrib.GetRequestObject(c).(*userLoginRequest)
	userProvider := dbopr.NewUserProvider()

	u, err := userProvider.CheckUserPassword(req.UserName, req.Password)
	if err != nil {
		abReq(c, http.StatusBadRequest, "password check failed.", err)
		return
	}

	// 如果用户点击了 记住密码，则有效期30天，否则有效期一星期
	var expireTime = 7 * 24 * 3600
	if req.Remember == 1 {
		expireTime = 30 * 24 * 3600
	}
	tokenProvider := dbopr.NewUserTokenProvider()
	token, err := tokenProvider.New(u.ID, expireTime)
	if err != nil {
		abReq(c, http.StatusInternalServerError, "new token failed.", err)
		return
	}

	var out = &userLoginResponse{
		UserID:       u.ID,
		UserName:     u.UserName,
		CreatedAt:    utils.Timetostr(u.CreatedAt),
		LastLogin:    u.GetLastLoginString(),
		Avatar:       u.Avatar,
		Role:         u.Role,
		AccessToken:  token.Token,
		RefreshToken: token.Refresh,
		ExpireAt:     token.Expire,
	}
	c.JSON(http.StatusOK, out)
}
